//
//  BCSAppDelegate.swift
//  BCSAppDelegate
//
//  Created by Basic on 2019/6/12.
//  接管系统 AppDelegate，分发事件（观察者模式）

import Foundation
import BCFileLog
import BCEventBus

#if ZHFLUTTER
import Flutter
#endif

open class BCSAppDelegate: UIResponder, UIApplicationDelegate {
    
    public var window: UIWindow?
    #if ZHFLUTTER
    ///flutter enging
    public var flutterEngine:FlutterEngine {
        if let engine = _flutterEngine {
            return engine
        }
        let engine = FlutterEngine(name: "zhihan flutter engine")
        _flutterEngine = engine
        return engine
    }
    public var _flutterEngine:FlutterEngine?
    ///flutter life cycle
    public lazy var lifeCycleDelegate:FlutterPluginAppLifeCycleDelegate = FlutterPluginAppLifeCycleDelegate()
    #endif
    
    
    //MARK: - life cycle
    open func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        var result = true
        #if ZHFLUTTER
        result = self.lifeCycleDelegate.application(application, willFinishLaunchingWithOptions: launchOptions ?? [:])
        #endif
        return result
    }
    open func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
        [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        BCLogInfo("[app] launch:\(launchOptions ?? [:])");
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self) { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:))) {
                _ = target.application?(application, didFinishLaunchingWithOptions: launchOptions)
            }
        }
        #if ZHFLUTTER
        self.setupFlutterModule()
        #endif
        var result = true
        #if ZHFLUTTER
        result = self.lifeCycleDelegate.application(application, didFinishLaunchingWithOptions: launchOptions ?? [:])
        #endif
        return result
    }
    
    open func applicationWillResignActive(_ application: UIApplication) {
//        BCLogInfo("[app] willResignActive");
    }
    
    open func applicationDidEnterBackground(_ application: UIApplication) {
        BCLogInfo("[app] didBack")
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.applicationDidEnterBackground(_:))) {
                target.applicationDidEnterBackground?(application)
            }
        })
    }
    
    open func applicationWillEnterForeground(_ application: UIApplication) {
//        BCLogInfo("[app] willEnterForeground");
    }
    
    open func applicationDidBecomeActive(_ application: UIApplication) {
        BCLogInfo("[app] didActive");
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.applicationDidBecomeActive(_:))) {
                target.applicationDidBecomeActive?(application)
            }
        })
    }
    
    open func applicationWillTerminate(_ application: UIApplication) {
        BCLogInfo("[app] terminate");
    }
    
    ///push
    open func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        BCLogInfo("[app] register push:\(deviceToken)");
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:didRegisterForRemoteNotificationsWithDeviceToken:))) {
                target.application?(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
            }
        })
        #if ZHFLUTTER
        self.lifeCycleDelegate.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
        #endif
    }
    open func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        BCLogInfo("[app] register push error:\(error.localizedDescription)");
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:didFailToRegisterForRemoteNotificationsWithError:))) {
                target.application?(application, didFailToRegisterForRemoteNotificationsWithError: error)
            }
        })
    }
    
//    public func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
//
//    }
    open func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {//ios7,app收到push消息
//        BCLogInfo("[app] receive:\(userInfo)");
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:))) {
                target.application?(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
            }
        })
        #if ZHFLUTTER
        self.lifeCycleDelegate.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
        #endif
    }
    
    //3D Touch 代理方法
    @available(iOS 9.0, *)
    open func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
        BCLogInfo("[app] shortcut:\(shortcutItem.type)")
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:performActionFor:completionHandler:))) {
                target.application?(application, performActionFor: shortcutItem, completionHandler: completionHandler)
            }
        })
        #if ZHFLUTTER
        self.lifeCycleDelegate.application(application, performActionFor: shortcutItem, completionHandler: completionHandler)
        #endif
    }
    
    
    @available(iOS 9.0, *)
    open func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        #if DEBUG
        NSLog("[app] open:\(url.absoluteString)")
        #endif
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:open:options:))) {
                let _ = target.application?(app, open: url, options: options)
            }
        })
        var result = true
        #if ZHFLUTTER
        result = self.lifeCycleDelegate.application(app, open: url, options: options)
        #endif
        return result
    }
    @available(iOS, deprecated: 9.0)
    open func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
        #if DEBUG
        NSLog("[app] handleOpen:\(url.absoluteString)")
        #endif
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:handleOpen:))) {
                let _ = target.application?(application, handleOpen: url)
            }
        })
        var result = true
        #if ZHFLUTTER
        result = self.lifeCycleDelegate.application(application, handleOpen: url)
        #endif
        return result
    }
    open func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        #if DEBUG
        NSLog("[app] continue:\(userActivity.webpageURL?.absoluteString ?? "")")
        #endif
        BCSEventBus<UIApplicationDelegate>.pubProtocol(UIApplicationDelegate.self, { (target) in
            if target.responds(to: #selector(UIApplicationDelegate.application(_:continue:restorationHandler:))) {
                let _ = target.application?(application, continue: userActivity, restorationHandler: restorationHandler)
            }
        })
        var result = true
        #if ZHFLUTTER
        result = self.lifeCycleDelegate.application(application, continue: userActivity, restorationHandler: { (params) in
            restorationHandler(params as? [UIUserActivityRestoring])
        })
        #endif
        return result
    }
    

    #if ZHFLUTTER
    //MARK: - flutter adapter
    /// 初始化flutter模块
    open func setupFlutterModule() {
        //子类可以重写flutter engine的初始化
    }
    #endif
}
